package com.newfiber.workflow.service.impl;

import com.newfiber.workflow.entity.WorkflowGroup;
import com.newfiber.workflow.entity.WorkflowUser;
import com.newfiber.workflow.service.FlowableUserService;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.IdentityService;
import org.flowable.idm.api.Group;
import org.flowable.idm.api.User;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

@Slf4j
@Service
public class FlowableUserServiceImpl implements FlowableUserService {

    @Resource
    private IdentityService identityService;

    private List<WorkflowUser> workflowUserList = new ArrayList<>();

    @Scheduled(cron = "0 0 0/1 * * ? ")
    public void syncUserInfo(){
	    workflowUserList = listUser();
	    for(WorkflowUser workflowUser : workflowUserList){
		    parseUserGroup(workflowUser);
	    }
    }

    @Override
    public List<WorkflowUser> listUser() {
        List<User> userList = identityService.createUserQuery().list();
        return WorkflowUser.build(userList);
    }

    @Override
    public List<WorkflowGroup> listGroup() {
        List<Group> groupList = identityService.createGroupQuery().list();
        return WorkflowGroup.build(groupList);
    }

	@Override
	public WorkflowUser getUser(String userId) {
    	if(StringUtils.isBlank(userId)){
    		return null;
	    }

		Optional<WorkflowUser> workflowUserOptional = workflowUserList.stream().filter(t -> t.getId().equals(userId)).findAny();
		if(workflowUserOptional.isPresent()){
			return workflowUserOptional.get();
		}

		User user = identityService.createUserQuery().userId(userId).singleResult();
		WorkflowUser workflowUser = WorkflowUser.build(user);

		parseUserGroup(workflowUser);

		workflowUserList.add(workflowUser);

		return workflowUser;
	}

	private void parseUserGroup(WorkflowUser workflowUser) {
		List<Group> groupList = identityService.createGroupQuery().groupMember(workflowUser.getId()).list();
		if(CollectionUtils.isEmpty(groupList)){
			return;
		}
		workflowUser.setWorkflowGroupList(WorkflowGroup.build(groupList));
		workflowUser.setUserGroups(groupList.stream().map(Group::getName).collect(Collectors.joining(",")));
	}
}
